{
    "cells": [
  {
   "cell_type": "markdown",
   "id": "354357ec",
   "metadata": {},
   "source": [
    "# KISS-ICP running on the NCLT MulRan Dataset\n",
    "\n",
    "The whole purpose of this notebook is to have a reproducable entry point for the experiments of the paper. You can also modify the system and just run this notebook to inspect the overall results.\n",
    "\n",
    "## Expected dataset layout\n",
    "\n",
    "```sh\n",
    "MulRan\n",
    "├── dcc\n",
    "│   ├── DCC01\n",
    "│   │   ├── data_stamp.csv\n",
    "│   │   ├── global_pose.csv\n",
    "│   │   ├── gps.csv\n",
    "│   │   ├── navtech_top_stamp.csv\n",
    "│   │   ├── Ouster\n",
    "│   │   │   ├── 1564718964199537916.bin\n",
    "│   │   │   ├── 1564718964300400595.bin\n",
    "│   │   │   ├── ...\n",
    "│   │   ├── ouster_front_stamp.csv\n",
    "│   │   └── xsens_imu.csv\n",
    "│   ├── DCC02\n",
    "│   └── DCC03\n",
    "├── kaist\n",
    "│   ├── KAIST01\n",
    "│   ├── KAIST02\n",
    "│   └── KAIST03\n",
    "├── riverside\n",
    "│   ├── Riverside01\n",
    "│   ├── Riverside02\n",
    "│   └── Riverside03\n",
    "└── sejong\n",
    "    ├── Sejong01\n",
    "    ├── Sejong02\n",
    "    └── Sejong03\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f223e79",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Install KISS-ICP and Plotting tools\n",
    "%pip install kiss-icp ipympl evo >/dev/null\n",
    "\n",
    "import os\n",
    "from pathlib import Path\n",
    "\n",
    "import kiss_icp\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from evo.tools import plot\n",
    "from kiss_icp.datasets import dataset_factory\n",
    "from kiss_icp.pipeline import OdometryPipeline\n",
    "\n",
    "%autoreload 2\n",
    "%matplotlib inline\n",
    "%matplotlib widget"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "365d344c",
   "metadata": {},
   "outputs": [],
   "source": [
    "data_root = os.environ.get(\"DATASETS\")\n",
    "data_dir = Path(os.path.join(data_root, \"MulRan\"))\n",
    "print(f\"Reading datasets from : {data_root}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f62877f",
   "metadata": {},
   "outputs": [],
   "source": [
    "from kiss_icp_eval import run_sequence\n",
    "\n",
    "\n",
    "def run_mulran_sequence(sequence: str):\n",
    "    sequence_dir = data_dir / sequence\n",
    "    return OdometryPipeline(\n",
    "        dataset=dataset_factory(\n",
    "            dataloader=\"mulran\",\n",
    "            data_dir=sequence_dir,\n",
    "        ),\n",
    "        deskew=True,\n",
    "    )\n",
    "\n",
    "\n",
    "all_sequences = {\n",
    "    \"kaist\": [\"kaist/KAIST01\", \"kaist/KAIST02\", \"kaist/KAIST03\"],\n",
    "    \"dcc\": [\"dcc/DCC01\", \"dcc/DCC02\", \"dcc/DCC03\"],\n",
    "    \"riverside\": [\n",
    "        \"riverside/Riverside01\",\n",
    "        \"riverside/Riverside02\",\n",
    "        \"riverside/Riverside03\",\n",
    "    ],\n",
    "    \"sejong\": [\"sejong/Sejong01\", \"sejong/Sejong02\", \"sejong/Sejong03\"],\n",
    "}\n",
    "\n",
    "\n",
    "kaist_results = {}\n",
    "for sequence in all_sequences[\"kaist\"]:\n",
    "    run_sequence(run_mulran_sequence, sequence=sequence, results=kaist_results)\n",
    "\n",
    "dcc_results = {}\n",
    "for sequence in all_sequences[\"dcc\"]:\n",
    "    run_sequence(run_mulran_sequence, sequence=sequence, results=dcc_results)\n",
    "\n",
    "riverside_results = {}\n",
    "for sequence in all_sequences[\"riverside\"]:\n",
    "    run_sequence(run_mulran_sequence, sequence=sequence, results=riverside_results)\n",
    "\n",
    "sejong_results = {}\n",
    "for sequence in all_sequences[\"sejong\"]:\n",
    "    run_sequence(run_mulran_sequence, sequence=sequence, results=sejong_results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "04ed61ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "from kiss_icp_eval import plot_trajectories, print_metrics_table"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "24ec9ad3",
   "metadata": {},
   "source": [
    "## Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3c17dfe",
   "metadata": {},
   "outputs": [],
   "source": [
    "print_metrics_table(kaist_results, \"KAIST\")\n",
    "plot_trajectories(kaist_results, close_all=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "984fb84e",
   "metadata": {},
   "outputs": [],
   "source": [
    "print_metrics_table(dcc_results, \"DCC\")\n",
    "plot_trajectories(dcc_results, close_all=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58cbbf36",
   "metadata": {},
   "outputs": [],
   "source": [
    "print_metrics_table(riverside_results, \"Riverside\")\n",
    "plot_trajectories(riverside_results, close_all=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c22aa4e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "print_metrics_table(sejong_results, \"Sejong\")\n",
    "plot_trajectories(sejong_results, close_all=False)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  },
  "vscode": {
   "interpreter": {
    "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
